Skip to content

3D 并行与混合并行策略 ​

标签
AI/infra/并行策略
字数
2047 字
阅读时间
9 分钟

前面每一篇都讲了一种并行策略。但真实的大模型训练从不是「只用一种」 —— 千卡级训练通常是 TP + PP + DP 的 3D 并行,加上 MoE 变成 4D,再加长序列就是 5D。

这一篇是并行策略的总装车间:多个维度怎么正交组合、通信域怎么映射到物理硬件、rank 怎么编排。

为什么必须混合 ​

每种单一策略都有天花板:

策略天花板
DP不省参数 —— 每卡仍装完整模型
TP出不了机 —— 通信太频繁
PP有 Bubble —— 且不省单层显存

但它们切的是不同的东西(状态冗余 / 单层权重 / 层),所以可以叠加:

world_size=TP×PP×DP(×EP×CP)

这个等式是硬约束 —— 任一维度的取值必须让乘积等于总卡数。它也是配置并行方案时第一个要满足的条件。

通信域划分:本篇的核心 ​

原则只有一条:把通信频率最高、带宽需求最大的维度放在最快的链路上。

维度通信频率数据量映射到
TP每层每个子模块都通信(80 层约 320 次)激活大小机内 NVLink(8 卡内)
CP / SPAttention 内通信序列维激活通常与 TP 同域或机内
PP每 micro-batch 边界一次激活大小可跨机 InfiniBand
DP每步一次梯度同步梯度大小跨节点,带宽要求最低

通信量从大到小:TP > CP > PP > DP;硬件带宽从高到低也是这个顺序 —— 两者恰好对应,这不是巧合,是把并行维度「按需求排序后映射到可用链路」的结果。

推导的依据在 03-多卡互联与集群网络:TP 跨机会比机内慢 18 倍,而 PP 的通信量小到 IB 完全够用。

把「按通信需求排序」映射到「按带宽排序」的链路上:

  通信量            并行维度        映射到
  最大  ┌────────┬──────────────┬──────────────────────┐
        │ TP     │ 每层每子模块  │ 机内 NVLink(8 卡内) │  900 GB/s
        │ CP/SP  │ Attention 内  │ 通常与 TP 同域        │
        │ PP     │ 每 micro-batch│ 可跨机 InfiniBand     │   50 GB/s
  最小  │ DP     │ 每步一次      │ 跨节点,要求最低      │
        └────────┴──────────────┴──────────────────────┘
                            ▲
                            └─ 两个顺序恰好一致 —— 不是巧合,
                               是把并行维度按需求排序后逐条映射的结果

rank 编排 ​

多维坐标映射 ​

每个 rank 映射到一个多维坐标:

rank  →  (tp_rank, pp_rank, dp_rank)

维度排列顺序有影响 —— 它决定「哪个维度贴近物理相邻的 GPU」。因为 NVLink 域(8 卡)是物理边界,TP 维度必须落在同一个 NVLink 域内,所以 TP 要排在最低位。

Megatron-LM 的 initialize_model_parallel() 做的就是这件事:按维度切分世界,为每个 rank 构造 (tp, pp, dp) 坐标。每个并行维度对应一组 NCCL communicator —— 所以维度越多,创建的通信组越多,初始化开销也越大。

判据 ​

TP 的 rank 集合必须落在一个 NVLink 域内。 若 TP=8 而单机也是 8 卡,则每 8 个连续 rank 构成一个 TP 组 —— rank 编号的连续性直接决定通信能不能走 NVLink。

这是「配置写错了性能差一半」的常见成因:代码逻辑全对,只是维度排列让 TP 跨了机。

64 卡(8 节点 × 8 GPU)配 TP=8、PP=4、DP=2 时的 rank 编排:

  节点 0            节点 1            节点 2            节点 3
  ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐
  │ rank 0–7     │ │ rank 8–15    │ │ rank 16–23   │ │ rank 24–31   │
  │ 一个 TP 组    │ │ 一个 TP 组    │ │ 一个 TP 组    │ │ 一个 TP 组    │
  │(NVLink 域内)│ │(NVLink 域内)│ │(NVLink 域内)│ │(NVLink 域内)│
  └──────┬───────┘ └──────┬───────┘ └──────┬───────┘ └──────┬───────┘
         └────────────────┴────────────────┴────────────────┘
              这 4 段是同一个 PP 组的 4 个 Stage,跨节点传激活(走 IB)

  剩下 32 卡是 DP=2 的另一份数据

  ⇒ TP 的 rank 集合必须落在同一个 NVLink 域内 ⇒ TP 维度排在最低位
  ⇒ 「代码逻辑全对,只是维度排列让 TP 跨了机」是性能差一半的常见成因

拓扑设计实战 ​

以 64 卡集群(8 节点 × 8 GPU) 为例,两种方案:

方案配置特点
ATP=8, PP=4, DP=2TP 吃满单机 8 卡;PP 跨 4 节点;DP=2
BTP=4, PP=8, DP=2TP 只用半机;PP 更多段

怎么取舍:

看什么倾向
模型层数多、单层小加大 PP(切层)
单层大加大 TP(切层内)
机间带宽紧张减少 PP(PP 跨机传激活),加大 DP
机内 NVLink 富余加大 TP

千卡级的经验做法:先按「装得下」定 TP 与 PP 的乘积,再用 DP 把卡数补满。因为 DP 的通信最便宜,多余卡优先给 DP。

加入 EP / CP 后,维度变成多维编排 —— 但要遵守同一条原则:按通信需求从高到低,依次映射到从快到慢的链路。

联合估算 ​

显存 ​

给定 (TP, PP, DP) 组合,每卡显存 = 参数 / 梯度 / 优化器状态按切分维度折算 + 激活。

这里要小心两处不均匀:

  • GQA 下 KV Head 数 < TP 度时,KV 权重切不均匀(见 08-张量并行与序列并行)
  • PP 的 Stage 负载不均(Embedding / Loss 层与 Transformer 层不同)

吞吐 ​

端到端吞吐的构成:

总时间=计算时间⏟可被并行度摊薄+各维度通信时间⏟频率×延迟+PP Bubble⏟占比×计算时间

注意括号里的标注 —— 三项随并行度的变化方向不同:

  • 计算时间随并行度下降
  • 通信时间随并行度上升(域越大,通信越贵)
  • Bubble 占比随 PP 度上升

所以「加卡一定更快」是错的 —— 存在一个最优点,超过它再加卡反而更慢。这个最优点的位置由「模型规模 / 集群拓扑 / 网络带宽」三者共同决定。

调参方法论 ​

先满足「装得下」→ 再优化「跑得快」

顺序不能反。显存不够时谈吞吐没有意义 —— 你连一次完整的前向都跑不完。这与 01-推理性能指标与瓶颈定位 里「先解决 OOM → 再攻 TTFT → 再攻 TPOT → 最后处理尾延迟」是同一条纪律。

这张图的完整形态 ​

把前面十篇拼起来:

                    ┌─ 单卡显存不够 ─┬─ 状态冗余装不下 → ZeRO / FSDP
                    │                 ├─ 单层装不下    → TP (+SP 补激活)
装不下 ─────────────┤                 ├─ 层数太多      → PP
                    │                 └─ 序列太长      → CP / Ring / Ulysses
                    │
                    └─ 单卡内部还能省 ─┬─ 降精度   → 混合精度 / FP8
                                       ├─ 时间换空间 → 梯度累积 / 激活重计算
                                       └─ 卸载      → ZeRO-Offload / Infinity

跑不完 ── 复制并行 → DP / DDP

组合全部维度 ──→ world_size = TP × PP × DP (× EP × CP)
                 通信域按「频率高→链路快」映射

判据始终是同一个:先问「瓶颈是哪一项」,再选手段。 这张图的分支顺序就是提问顺序。

相关 ​

参考 ​

贡献者 ​

文件历史 ​